#include <iostream>
#include <string>
#include <cerrno>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "nocopy.hpp"
#include "Log.hpp"
#include "comm.hpp"
#include "InetAddr.hpp"

const static uint16_t defaultport = 8888;
const static int defaultfd = -1;
const static int defaultsize = 1024;

class UdpServer :public nocopy
{
public:
    UdpServer(uint16_t port = defaultport)
        :_port(port), _sockfd(defaultfd)
        {}
    void Init()
    {
        // 1.创建socket， 就是创建了文件细节
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(_sockfd < 0)
        {
            lg.LogMessage(Fatal, "socket err, %d : %s\n", errno, strerror(errno));
            exit(Socket_err);
        }

        lg.LogMessage(Info, "socket success, sockfd: %d\n", _sockfd);

        // 添加地址重用选项
        int opt = 1;
        setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

        // 2.绑定， 指定网络信息
        struct sockaddr_in local;
        bzero(&local, sizeof(local));  //将sockaddr_in local中的内容全部设定为0
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        local.sin_addr.s_addr = INADDR_ANY; // 0
        // local.sin_addr.s_addr = htonl(INADDR_ANY);  // 修改这里，使用INADDR_ANY

        //  结构体填完， 设置到内核中了吗？？ 没有
        int n = ::bind(_sockfd, (struct sockaddr *)&local, sizeof(local));
        if(n != 0)
        {
            lg.LogMessage(Fatal, "bind err, %d : %s\n", errno, strerror(errno));
            exit(Bind_Err);
        }
        
        lg.LogMessage(Info, "bind success\n");  // 添加绑定成功的日志

    }
    void Start()
    {
        char buffer[defaultsize];
        std::cout << "Server is running on port: " << _port << std::endl << std::flush;
        while(true)
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            ssize_t n = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &len);
            if(n > 0)
            {

                InetAddr addr(peer);
                uint16_t clientport = ntohs(peer.sin_port);
                std::string clientip = inet_ntoa(peer.sin_addr);

                

                buffer[n] = 0;
                std::cout << "[" << "clientinfo" << "]#" << buffer << std:: endl;
                std::cout << "client say#" << buffer << std::endl << std::flush;
                std::cout << "client addr: " << inet_ntoa(peer.sin_addr) << ":" << ntohs(peer.sin_port) << std::endl << std::flush;

                const char* response = "Message received!";
                ssize_t s = sendto(_sockfd, response, strlen(response), 0, (struct sockaddr*)&peer, len);
                if(s < 0)
                {
                    lg.LogMessage(Error, "sendto failed: %s\n", strerror(errno));
                    perror("sendto");  // 添加更详细的错误信息
                }
                else
                {
                    std::cout << "Sent " << s << " bytes to client" << std::endl << std::flush;
                }
            }
            else if(n < 0)
            {
                lg.LogMessage(Error, "recvfrom failed: %s\n", strerror(errno));
            }
        }
    }

    ~UdpServer()
    {
    }

private:
    std::string _ip;
    uint16_t _port;
    int _sockfd;
};

//sudo netstat -anup 查询